### 在此文件中具体实现各种类型的pulse(gate)，同时进一步明确每种pulse所对应的硬件接口
from cion.gates import *
#from AD9910 import AD9910
from time import time
# Labbrick是本配置文件所涉及到的一系列实验中额外要用的实验硬件，仅仅在Doppler_Only这个gate中用到
# 在其他配置文件中，用户也可以单独引入自己要用的硬件接口
from labbrick.labbrick import Labbrick

Doppler_chapter_dict = {
    'Doppler':'00000000 00000000 00001111,[10000000 00000000 00000000, 1],[10000000 00000000 00010000,1]', 
    'Zero': '11000000 10000000 00000000', 
    'Strong': '11111111 11111111 11111111,[10000000 00000000 00000000, 1],[10000000 00000000 00010000,1]'
              }

Exp_chapter_dict = {
    'Doppler':'00000000 00000000 00000000', 
    'Doppler_Only':'00000000 00000000 00001111,[10000000 00000000 00000000, 1],[10000000 00000000 00010000,1]',
    'Pumping':  '01100000 11000000 00000000', 
    'Microwave': '10000000 00100000 00000000',
    'Detection':'01010000 10000000 00001111,[11000000 00000000 00000000, 1],[11000000 00000000 00010000,1]', 
    'Raman':  '11000000 10010000 00000000',
    'Zero': '11000000 10000000 00000000', 
    'Strong': '11111111 11111111 11111111'
              }

if Global_Setting.get_debug_mode() == False:
    labbrick_doppler = Labbrick(serial_port = "COM3")
    labbrick_370_lock_EOM = Labbrick(serial_port = "COM4", mode=1)

class Doppler(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Doppler"):
        super().__init__(duration, latency, awg_flag, 'Doppler', amp, freq, phase, label)
        #self.hardware = labbrick_doppler
    
    def update_hardware(self):
        #print("Update Doppler with ", "amp:", self.amp, "freq:", self.freq, "duration: ", self.duration,str(time()))
        #labbrick_370_lock_EOM.freq_update(self.freq)
        None
        
    def reset_hardware(self):
        #labbrick_doppler.freq_update(165)
        None
        
class Doppler_Only(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Doppler_Only"):
        super().__init__(duration, latency, awg_flag, 'Doppler_Only', amp, freq, phase, label)
        #self.hardware = labbrick_doppler
    
    def update_hardware(self):
        #print("Update Doppler with ", "amp:", self.amp, "freq:", self.freq, "duration: ", self.duration,str(time()))
        labbrick_370_lock_EOM.freq_update(self.freq)
        None
        
    def reset_hardware(self):
        #labbrick_doppler.freq_update(165)
        None
        
class Strong(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Strong"):
        super().__init__(duration, latency, awg_flag, 'Strong', amp, freq, phase, label)
        self.hardware = None
    
    def update_hardware(self):
        print("Update Doppler with ", "amp:", self.amp, "freq:", self.freq, "duration: ", self.duration,str(time()))
        self.hardware.freq_update(self.freq)
        self.hardware.amp_update(self.amp)    
        
class Detection(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Detection"):
        super().__init__(duration, latency, awg_flag, 'Detection', amp, freq, phase, label)

    def direct_update_hardware(self):
        assert Detection.hardware_amp != None and Detection.hardware_freq != None and Detection.hardware_phase != None
        pass#return AD9910.WriteProf(1, 3, hardware_amp, hardware_freq, hardware_phase)

    
class Pumping(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Pumping"):
        super().__init__(duration, latency, awg_flag, 'Pumping', amp, freq, phase, label)

    def direct_update_hardware(self):
        assert Optical_pumping.hardware_amp != None and Optical_pumping.hardware_freq != None and Optical_pumping.hardware_phase != None
        pass#return AD9910.WriteProf(1, 3, hardware_amp, hardware_freq, hardware_phase)

class Microwave(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = True, amp = None, freq = None, phase = None, label = "Microwave"):
        super().__init__(duration, latency, awg_flag, 'Microwave', amp, freq, phase, label)

    def direct_update_hardware(self):
        assert Optical_pumping.hardware_amp != None and Optical_pumping.hardware_freq != None and Optical_pumping.hardware_phase != None
        pass#return AD9910.WriteProf(1, 3, hardware_amp, hardware_freq, hardware_phase)

    def update_hardware(self):
        #print("Update Doppler with ", "amp:", self.amp, "freq:", self.freq, "duration: ", self.duration,str(time()))
        #labbrick_370_lock_EOM.freq_update(self.freq)
        None
        
    def reset_hardware(self):
        #labbrick_doppler.freq_update(165)
        None
        
class Zero(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Zero"):
        super().__init__(duration, latency, awg_flag, 'Zero', amp, freq, phase, label)

class Microwave(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Microwave"):
        super().__init__(duration, latency, awg_flag, 'Microwave', amp, freq, phase, label)

    def direct_update_hardware(self):
        pass
    
    def reset_hardware(self):
        pass

class Raman(BaseGate):
    hardware_amp, hardware_freq, hardware_phase = None, None, None
    def __init__(self, duration, latency = 0, awg_flag = None, amp = None, freq = None, phase = None, label = "Raman"):
        super().__init__(duration, latency, awg_flag, 'Raman', amp, freq, phase, label)

    def direct_update_hardware(self):
        pass

    def reset_hardware(self):
        pass

